#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <json-c/json_object.h>
#include <json-c/json_tokener.h>

#include "../lib/util.h"
#include "../aslstatus.h"
#include "../components_config.h"

#define IP_API_KEY "4da6304cf5bfa3eb484b7a579f47aee8"

typedef struct {
	char *response;
	size_t size;
} DATA;

typedef struct {
	float lat;
	float lon;
} location;

size_t data_callback(void *data, size_t size, size_t n_mb, void *userdata_p) {
	size_t real_size = size * n_mb;
	DATA *userdata = (DATA *) userdata_p;
	char *ptr;

	if ((ptr = realloc(userdata->response, userdata->size + real_size + 1)) == NULL) {
		fprintf(stderr, "Error reallocating memory");
		return 0;
	}

	userdata->response = ptr;
	memcpy(&(userdata->response[userdata->size]), data, real_size);
	userdata->size += real_size;
	userdata->response[userdata->size] = 0;

	return real_size;
}

void weather(char *out, char __unused *_a, uint32_t __unused _i, void __unused *_p) {
	CURL *curl;
	CURLcode curl_result;
	DATA data = {0};
	json_object *root, *lat, *lon, *openweather_temp;
	location loc = {0};
	char openweather_URL[1000];

	if (!(curl = curl_easy_init()))
		ERRRET(out);

	curl_easy_setopt(curl, CURLOPT_URL, "http://ip-api.com/json/");
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, data_callback);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &data);

	if ((curl_result = curl_easy_perform(curl)) != CURLE_OK)
		ERRRET(out);

	if ((root = json_tokener_parse(data.response)) == NULL)
		ERRRET(out);

	if (!(json_object_object_get_ex(root, "lat", &lat) && json_object_object_get_ex(root, "lon", &lon)))
		ERRRET(out);

	loc.lat = (float) json_object_get_double(lat);
	loc.lon = (float) json_object_get_double(lon);

	sprintf(openweather_URL, "http://api.openweathermap.org/data/2.5/weather?lat=%f&lon=%f&appid=%s&units=%s", 
									loc.lat, loc.lon, IP_API_KEY, "imperial");
	data.size = 0;
	curl_easy_setopt(curl, CURLOPT_URL, openweather_URL);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, data_callback);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &data);

	if ((curl_result = curl_easy_perform(curl)) != CURLE_OK)
		ERRRET(out);

	if ((root = json_tokener_parse(data.response)) == NULL)
		ERRRET(out);
	if (!(json_object_object_get_ex(root, "main", &root)))
		ERRRET(out);
	if (!(json_object_object_get_ex(root, "temp", &openweather_temp)))
		ERRRET(out);

	sprintf(out, "%.2f\n", json_object_get_double(openweather_temp));

	free((data.response));

	curl_easy_cleanup(curl);
}
